package edu.hda.pt.server.connections;

import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

import edu.hda.pt.server.PTServer;
import edu.hda.pt.server.connections.rmi.StreamThread;
import edu.hda.pt.utils.Stream;
import edu.hda.pt.utils.TestObject;
import edu.hda.pt.utils.Stream.StreamState;
import edu.hda.pt.utils.connections.rmi.PTClientRMICallbackI;
import edu.hda.pt.utils.connections.rmi.PTServerRMII;

/**
 * Server implementation for the connection method Java RMI
 * 
 * @author Marc Hammerton
 * 
 */
public class PTServerRMI extends PTServer implements PTServerRMII {

	private String serverIPAddress;
	private StreamThread st = null;

	/**
	 * Constructor for initializing the serverIPAddress
	 * 
	 * @param args
	 */
	public PTServerRMI(String[] args) {
		if (args.length == 3) {
			serverIPAddress = args[2];
		} else {
			serverIPAddress = "127.0.0.1";
		}
	}

	/**
	 * @see edu.hda.pt.server.PTServer#start()
	 */
	@Override
	public void start() {
		try {
			LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
			PTServerRMII stub = (PTServerRMII) UnicastRemoteObject
					.exportObject(this, 0);
			Registry registry = LocateRegistry
					.getRegistry(this.serverIPAddress);
			registry.rebind("PTServerRMI", stub);

			st = new StreamThread();
			st.start();
		} catch (RemoteException e) {
			e.printStackTrace();
		}

	}

	/**
	 * @see edu.hda.pt.server.PTServer#stop()
	 */
	@Override
	public void stop() {
	}

	/**
	 * @see edu.hda.pt.utils.connections.rmi.PTServerRMII#getBool(boolean)
	 */
	@Override
	public boolean getBool(boolean data) {
		boolean response = handleBool(data);
		return response;
	}

	/**
	 * @see edu.hda.pt.utils.connections.rmi.PTServerRMII#getBytes(byte[])
	 */
	@Override
	public byte[] getBytes(byte[] data) {
		byte[] response = handleBytes(data);
		return response;
	}

	/**
	 * @see edu.hda.pt.utils.connections.rmi.PTServerRMII#getInteger(int)
	 */
	@Override
	public int getInteger(int data) {
		int response = handleInteger(data);
		return response;
	}

	/**
	 * @see edu.hda.pt.utils.connections.rmi.PTServerRMII#getLong(long)
	 */
	@Override
	public long getLong(long data) {
		long response = handleLong(data);
		return response;
	}

	/**
	 * @see edu.hda.pt.utils.connections.rmi.PTServerRMII#getObject(edu.hda.pt.utils
	 *      .TestObject)
	 */
	@Override
	public TestObject getObject(TestObject data) {
		TestObject response = handleObject(data);
		return response;
	}

	/**
	 * @see edu.hda.pt.utils.connections.rmi.PTServerRMII#getString(java.lang.String)
	 */
	@Override
	public String getString(String data) {
		String response = handleString(data);
		return response;
	}

	/**
	 * @see edu.hda.pt.utils.connections.rmi.PTServerRMICallbackI#handleStream(edu
	 *      .hda.pt.utils.Stream)
	 */
	@Override
	public Stream handleStream(Stream stream, PTClientRMICallbackI client)
			throws RemoteException {

		if (stream.getState() == StreamState.START) {

			// Init StreamThread
			if (st.getFileSize() == 0) {
				synchronized (st) {
					st.setFileSize(stream.getFs());
					st.addClient(client);
					st.notify();
				}

			} else if (stream.getFs() == st.getFileSize()) {
				synchronized (st) {
					st.addClient(client);
				}
			}
			stream.setState(StreamState.RUNNING);

		} else if (stream.getState() == StreamState.FINISH) {
			st.removeClient(client);

			stream.setState(StreamState.STOPPED);
		}

		return stream;
	}

}
